<?php


namespace app\common\model;


use app\lib\exception\BaseException;
use think\facade\Cache;
use think\Model;
use tools\jwt\Token;

class BaseModel extends Model
{
    // 可写入字段
    protected $createFields = [];
    // 可更新字段
    protected $updateFields = [];
    /**
     * 判断登录类型并判断是否存在
     * @param array $arr
     * @return User|bool
     */
    public function isExists($arr =[])
    {
        if(!is_array($arr)) return false;
        if(array_key_exists('phone',$arr)){
            //是手机号
            $user = $this->where('phone',$arr['phone'])->find();
            if($user) $user->logintype = 'phone';
            return $user;
        }
        //用户id
        if(array_key_exists('id',$arr)){
            return $this->where('id',$arr['id'])->find();
        }
        //邮箱
        if(array_key_exists('email',$arr)){
            $user = $this->where('email',$arr['email'])->find();
            if($user) $user->logintype = 'email';
            return $user;
        }
        //账号(用户名)
        if(array_key_exists('username',$arr)){
            $user = $this->where('username',$arr['username'])->find();
            if ($user) $user->logintype = 'username';
            return $user;
        }
        //第三方参数
        if (array_key_exists('provider',$arr))
        {
            $where = [
                'type' => $arr['provider'],
                'openid' => $arr['openid']
            ];
            $user = $this->userbind()->where($where)->find();
            if($user) $user->logintype = $arr['provider'];
            return $user;
        }
        return false;
    }

    /**
     * 检查是否被禁用账号
     * @param $arr
     * @param bool $isReget
     * @return mixed
     * @throws BaseException
     */
    public function checkStatus($arr,$isReget = false)
    {
        $status = 1;
        if($isReget){
            //账号密码登录 和第三方登录
            $userId = array_key_exists('user_id',$arr)?$arr['user_id']:$arr['id'];
            //判断第三方登录是否绑定了手机号
            if($userId < 1) return $arr;
            //查询user表
            $user = $this->find($userId)->toArray();
            //拿到status
            $status = $user['status'];
        }else{
            $status = $arr['status'];
        }
        if($status == 0) throw new BaseException(['code' => 200, 'msg' => '该用户已被禁用','errorCode' => 20001]);
        return $arr;
    }

    /**
     * 检查密码
     * @param $password
     * @param $hash
     * @return bool
     * @throws BaseException
     */
    public function  checkPassword($password,$hash){
        if(!$hash) throw new BaseException(['code'=>200,'msg'=>'密码错误','errorCode' => 20002]);
        //密码错误
        if(!password_verify($password,$hash)) throw new BaseException(['code' => 200, 'msg'=>'密码错误','errorCode'=>20002]);
        return true;
    }

    /**
     * 创建token
     * @param array $arr
     * @param string $type
     * @return array
     * @throws BaseException
     */
    public function CreateSaveToken($arr = [],$type="")
    {
        //生成token
        $token=Token::getToken($arr['id']);
        $arr['token'] = $token;
//        从token中获取用户id备用
//        $user_id = Token::getUserId($token)
        //登录过期时间
        $expire = array_key_exists($type.'expire_in',$arr)?$arr[$type.'expire_in']:config($type == ''?'api':'admin'.'.token_expire');
        //保存到缓存中
        if(!Cache::set($token,$arr,$expire)) throw new BaseException();
        //返回token
        return $token;
    }

    /**
     * 判断账号是手机号还是邮箱还是账号
     * @param $data
     * @return array
     */
    public function filterUserData($data)
    {
        $arr = [];
        //验证是否是手机号码
        if(preg_match('^1(3|4|5|7|8|9)[0-9]\d{8}$^',$data)){
            $arr['phone'] = $data;
            return $arr;
        }
        //验证是否是邮箱
        if(preg_match('/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,})$/', $data)){
            $arr['email'] = $data;
            return $arr;
        }
        //否则就是账号
        $arr['username'] = $data;
        return $arr;
    }

    /**
     * 模型事件
     */
    // 查询后
    public static function onAfterRead($M){

    }
    // 写入前
    public static function onBeforeWrite($M){
        // 过滤可写入字段
        if (!empty($M->createFields)) {
            $M->allowField($M->createFields);
        }
    }
    // 更新前
    public static function onBeforeUpdate($M){
        // 过滤可更新字段
        if (!empty($M->updateFields)) {
            $M->allowField($M->updateFields);
        }
    }

    // 定义全局的查询范围

    /**
     * 封装简化查询范围（更加语义化，重要）
     */
    // 开启状态
    public function scopeStatus($query,$status = 1){
        $query->where('status',$status);
    }

    // 搜索器（非常重要）
    // 创建时间
    public function searchCreateTimeAttr($query, $value, $data)
    {
        $query->whereBetweenTime('create_time', $value[0], $value[1]);
    }

    // 更新时间
    public function searchUpdateTimeAttr($query, $value, $data)
    {
        $query->whereBetweenTime('update_time', $value[0], $value[1]);
    }

    // 获取器（处理输出字段）
    // 常用增删改查方法
    /**
     * 1. 修改状态
     * 前提：
     * (1) 参数：id和status
     * (2) 使用 validate 的isExist
     */
    public function _UpdateStatus()
    {
        $request = request();
        return $request->Model->save([
            'status'=>$request->param('status')
        ]);
    }

    // 判断当前用户是否有操作该信息的权限
    public function __checkActionAuth(){
        $request = request();
        if ($request->Model->user_id !== $request->UserModel->id) {
            return ApiException('非法操作');
        }
    }

    // 列表
    public function Mlist(){
        $param = request()->param();
        $limit = intval(getValByKey('limit',$param,10));
        $page = intval(getValByKey('page',$param,1));
        $totalCount = $this->count();
        $list = $this->page($page,$limit)->order([
            'order'=>'desc',
            'id'=>'desc'
        ])->select();
        return [
            'list'=>$list,
            'totalCount'=>$totalCount
        ];
    }

    // 移除多余字段
    public function unsetCommonParams($param){
        if(array_key_exists("create_time",$param)){
            unset($param["create_time"]);
        }
        if(array_key_exists("update_time",$param)){
            unset($param["update_time"]);
        }
        return $param;
    }

    // 创建
    public function Mcreate(){
        $param = $this->unsetCommonParams(request()->param());
        return $this->create($param);
    }
    // 修改
    public function Mupdate(){
        $param = $this->unsetCommonParams(request()->param());
        return $this->save($param);
    }
    // 删除
    public function Mdelete(){
        return request()->Model->delete();
    }

    /**
     * 删除多个
     * @return bool
     * @throws \Exception
     */
    public function MdeleteAll(){
        $param = request()->param('ids');
        // 找到所有数据并删除
        return $this->where('id','in',$param)->delete();
    }
}